home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / hard / drivr / BetaScan_1.12.lha / BetaScan / ScannerDev / packer.c < prev    next >
C/C++ Source or Header  |  1998-10-04  |  3KB  |  125 lines

  1. /*----------------------------------------------------------------------*
  2.  * packer.c Convert data to "cmpByteRun1" run compression.     11/15/85
  3.  *
  4.  * By Jerry Morrison and Steve Shaw, Electronic Arts.
  5.  * This software is in the public domain.
  6.  *
  7.  *    control bytes:
  8.  *     [0..127]   : followed by n+1 bytes of data.
  9.  *     [-1..-127] : followed by byte to be repeated (-n)+1 times.
  10.  *     -128       : NOOP.
  11.  *
  12.  * This version for the Commodore-Amiga computer.
  13.  *----------------------------------------------------------------------*/
  14. #include <exec/types.h>
  15. #include "packer.h"
  16.  
  17. #define DUMP    0
  18. #define RUN    1
  19.  
  20. #define MinRun 3    
  21. #define MaxRun 128
  22. #define MaxDat 128
  23.  
  24. static LONG putSize;
  25.  
  26. #define GetByte()    (*source++)
  27. #define PutByte(c)    { *dest++ = (c);   ++putSize; }
  28.  
  29. static char buf[256];    /* [TBD] should be 128?  on stack?*/
  30.  
  31. static BYTE *PutDump( BYTE *dest,int nn)
  32. {
  33.   int i;
  34.  
  35.   PutByte(nn-1);
  36.   for( i = 0 ; i < nn ; i++)
  37.     PutByte(buf[i]);
  38.   return(dest);
  39. }
  40.  
  41. static BYTE *PutRun(BYTE *dest,int nn,int cc)
  42. {
  43.     PutByte(-(nn-1));
  44.     PutByte(cc);
  45.     return(dest);
  46. }
  47.  
  48. #define OutDump(nn)   dest = PutDump(dest, nn)
  49. #define OutRun(nn,cc) dest = PutRun(dest, nn, cc)
  50.  
  51. /*----------- PackRow --------------------------------------------------*/
  52. /* Given POINTERS TO POINTERS, packs one row, updating the source and
  53.    destination pointers.  RETURNs count of packed bytes.*/
  54. ULONG PackRow(BYTE* source,BYTE* dest,ULONG rowSize)
  55. {
  56.   char c,lastc = '\0';
  57.   BOOL mode = DUMP;
  58.   short nbuf = 0;        /* number of chars in buffer */
  59.   short rstart = 0;    /* buffer index current run starts */
  60.  
  61.   putSize = 0;
  62.   buf[0] = lastc = c = GetByte();  /* so have valid lastc */
  63.   nbuf = 1;
  64.   rowSize--;    /* since one byte eaten.*/
  65.  
  66.   for( ; rowSize ; --rowSize )
  67.   {
  68.     buf[nbuf++] = c = GetByte();
  69.     switch( mode )
  70.     {
  71.       case DUMP:
  72.         /* If the buffer is full, write the length byte then the data */
  73.         if( nbuf>MaxDat )
  74.         {
  75.           OutDump(nbuf-1);  
  76.           buf[0] = c; 
  77.           nbuf = 1;
  78.           rstart = 0; 
  79.           break;
  80.         }
  81.  
  82.         if( c == lastc )
  83.         {
  84.           if( nbuf-rstart >= MinRun )
  85.           {
  86.             if( rstart > 0 )
  87.             OutDump(rstart);
  88.             mode = RUN;
  89.           }
  90.           else if( rstart == 0 )
  91.             mode = RUN;    /* no dump in progress, so can't lose by making these 2 a run.*/
  92.         }
  93.         else
  94.           rstart = nbuf-1;  /* first of run */ 
  95.         break;
  96.  
  97.       case RUN:
  98.         if( (c != lastc) || (nbuf-rstart > MaxRun) )
  99.         {
  100.           /* output run */
  101.           OutRun(nbuf-1-rstart,lastc);
  102.           buf[0] = c;
  103.           nbuf = 1; rstart = 0;
  104.           mode = DUMP;
  105.         }
  106.         break;
  107.     }
  108.  
  109.     lastc = c;
  110.   }
  111.  
  112.   switch( mode )
  113.   {
  114.     case DUMP:
  115.       OutDump(nbuf);
  116.       break;
  117.     case RUN:
  118.       OutRun(nbuf-rstart,lastc);
  119.       break;
  120.     }
  121.   if( putSize & 0x01 )
  122.     PutByte(-128);
  123.   return (ULONG)putSize;
  124. }
  125.